// ----------------------------------
// projects/c++/collatz/TestCollatz.h
// Copyright (C) 2009
// Glenn P. Downing
// ----------------------------------

#ifndef TestCollatz_h
#define TestCollatz_h

// --------
// includes
// --------

#include <sstream> // istringtstream, ostringstream
#include <string>  // ==

#include "cppunit/TestFixture.h"             // TestFixture
#include "cppunit/extensions/HelperMacros.h" // CPPUNIT_TEST, CPPUNIT_TEST_SUITE, CPPUNIT_TEST_SUITE_END

// -----------
// TestCollatz
// -----------

struct TestCollatz : CppUnit::TestFixture {
    // ----
    // read
    // ----

    void test_read () {
        std::istringstream in("1 10\n");
        const bool b = read(in);
        CPPUNIT_ASSERT(b == true);
        CPPUNIT_ASSERT(i ==    1);
        CPPUNIT_ASSERT(j ==   10);}

    // ----
    // eval
    // ----

    void test_eval_1 () {
        i =  1;
        j = 10;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 20);}

    void test_eval_2 () {
        i = 100;
        j = 200;
        v =   0;
        eval();
        CPPUNIT_ASSERT(v == 125);}

    void test_eval_3 () {
        i = 201;
        j = 210;
        v =   0;
        eval();
        CPPUNIT_ASSERT(v == 89);}

    void test_eval_4 () {
        i =  900;
        j = 1000;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 174);}

    void test_eval_5 () {
        i =  123613;
        j = 141;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 354);}

    void test_eval_6 () {
        i =  23578;
        j = 39873;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 324);}

    void test_eval_7 () {
        i = 11111;
        j = 22222;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 279);}

    void test_eval_8 () {
        i =  3;
        j = 52;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 112);}

    void test_eval_9 () {
        i = 999999;
        j = 999998;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 259);}

    void test_eval_10 () {
        i = 1;
        j = 999999;
        v =    0;
        eval();
        CPPUNIT_ASSERT(v == 525);}

    void test_eval_11 () {
        i =  1;
        j = 1000;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 179);}

    void test_eval_12 () {
        i =  2;
        j =  3;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 8);}

    void test_eval_13 () {
        i =  125;
        j = 13245;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 268);}

    void test_eval_14 () {
        i =  98763;
        j =  24578;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 351);}

    void test_eval_15 () {
        i =  1;
        j =  1;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 1);}

    void test_eval_16 () {
        i =  345;
        j =  865;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 171);}

    void test_eval_17 () {
        i =  33333;
        j =  44444;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 324);}

    void test_eval_18 () {
        i =  200;
        j =  201;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 27);}

    void test_eval_19 () {
        i =  1246;
        j =  1250;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 177);}

    void test_eval_20 () {
        i =  99999;
        j =  100001;
        v =  0;
        eval();
        CPPUNIT_ASSERT(v == 227);}

    // -----
    // print
    // -----

    void test_print () {
        i =  1;
        j = 10;
        v = 20;
        std::ostringstream out;
        print(out);
        CPPUNIT_ASSERT(out.str() == "1 10 20\n");}

    // -----
    // suite
    // -----

    CPPUNIT_TEST_SUITE(TestCollatz);
    CPPUNIT_TEST(test_read);
    CPPUNIT_TEST(test_eval_1);
    CPPUNIT_TEST(test_eval_2);
    CPPUNIT_TEST(test_eval_3);
    CPPUNIT_TEST(test_eval_4);
    CPPUNIT_TEST(test_eval_5);
    CPPUNIT_TEST(test_eval_6);
    CPPUNIT_TEST(test_eval_7);
    CPPUNIT_TEST(test_eval_8);
    CPPUNIT_TEST(test_eval_9);
    CPPUNIT_TEST(test_eval_10);
    CPPUNIT_TEST(test_eval_11);
    CPPUNIT_TEST(test_eval_12);
    CPPUNIT_TEST(test_eval_13);
    CPPUNIT_TEST(test_eval_14);
    CPPUNIT_TEST(test_eval_15);
    CPPUNIT_TEST(test_eval_16);
    CPPUNIT_TEST(test_eval_17);
    CPPUNIT_TEST(test_eval_18);
    CPPUNIT_TEST(test_eval_19);
    CPPUNIT_TEST(test_eval_20);
    CPPUNIT_TEST(test_print);
    CPPUNIT_TEST_SUITE_END();};

#endif // TestCollatz_h
